package com.kanshu.utils;

import com.kanshu.constant.OnlineType;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author GAIst
 * ClassName FileUtil.java
 * From
 * Description OK
 * createTime 2024年12月20日14:32:26
 */
public class FileUtil {
    /**
     * 根据绝对路径查找文件
     * 此方法旨在遍历指定路径下的所有文件，并返回文件名列表
     * 如果指定路径不是一个有效的目录，方法将返回"null"
     *
     * @param absolutePath 字符串类型，指定要遍历的目录的绝对路径
     * @return 字符串类型，包含所有文件名的逗号分隔列表，如果没有文件或路径无效则返回"null"
     */
    public static String findFileByPath(String absolutePath){
        // 初始化结果字符串，用于存储文件名列表
        String result = "";
        // 创建一个File对象，表示指定路径的目录
        File directory = new File(absolutePath);

        // 检查目录是否存在且为目录类型
        if (directory.exists() && directory.isDirectory()) {
            // 获取目录下的所有文件数组
            File[] files = directory.listFiles();
            // 如果文件数组不为空，则遍历所有文件
            if (files != null) {
                StringBuilder stringBuilder = new StringBuilder();
                for (File file : files) {
                    // 将文件名添加到结果字符串中，用逗号分隔
                    stringBuilder.append(file.getName()).append(",");
                }
                result = stringBuilder.toString();
            }
        } else {
            // 如果指定路径不是一个有效的目录，打印错误信息并返回"null"
            System.out.println("The specified path is not a valid directory.");
            result = "null";
        }
        // 返回结果字符串
        return result;
    }

    /**
     * 将包含多部小说名称的字符串分割成单个小说名称数组
     * 此方法假设小说名称之间由逗号分隔
     *
     * @param allNovels 包含多部小说名称的字符串，小说名之间以逗号分隔
     * @return 分割后的单个小说名称数组
     */
    public static String[] splitNovels(String allNovels){
        // 使用逗号作为分隔符，将包含多部小说的字符串分割成单个小说名称数组
        return allNovels.split(",");
    }

    /**
     * 根据索引获取小说文件名
     * 该方法主要用于从一个小说文件名列表中，根据给定的索引值，提取出不带扩展名的小说文件名
     *
     * @param novelList 包含小说文件名的字符串数组，每个文件名应包含扩展名，用于区分和选择小说文件
     * @param index 小说文件名在列表中的索引位置，注意这里的索引是从1开始计数的，而非从0开始
     * @return 返回对应索引位置小说文件名的主名称部分（不包含扩展名的部分）
     */
    public static String getFileName(String[] novelList, int index){
        // 将传入的索引值减1，以匹配数组索引从0开始的规则
        index = index - 1;
        // 返回指定索引位置的小说文件名的主名称部分，通过"."分割字符串，取第一部分
        return novelList[index].split("\\.")[0];
    }

    /**
     * 根据文件的绝对路径和索引获取文件的语言
     * 该方法旨在通过文件路径和特定索引来检索文件语言，主要为了处理小说文件
     *
     * @param absolutePath 文件的绝对路径，用于定位文件
     * @param index 文件索引，用于指定需要获取语言的文件
     * @return 返回根据索引找到的文件的语言，如果未找到或发生异常，则返回null
     */
    public static String getFileLan(String absolutePath, int index){
        // 通过绝对路径查找文件
        String all = FileUtil.findFileByPath(absolutePath);
        // 分割文件并根据索引获取文件名
        return FileUtil.getFileName(FileUtil.splitNovels(all), index);
    }

    /**
     * 分页获取文件内容
     *
     * @param filePath 文件的绝对路径
     * @param pageNumber 页码，从1开始
     * @param pageSize 每页大小
     * @return 指定页的内容
     * @throws IOException 如果文件读取过程中发生错误
     */
    public static String getPageContent(String filePath, int pageNumber, int pageSize) throws IOException {
        // 创建一个File对象，表示指定路径的文件
        File file = new File(filePath);

        // 检查文件是否存在且为文件类型
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在或不是一个有效的文件");
        }

        // 初始化结果列表，用于存储文件内容
        List<String> lines = new ArrayList<>();
        // 使用BufferedReader读取文件内容
        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = br.readLine()) != null) {
                lines.add(line);
            }
        }

        // 计算起始索引和结束索引
        int startIndex = (pageNumber - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, lines.size());

        // 检查页码是否有效
        if (startIndex >= lines.size()) {
            return "";
            // 页码超出范围，返回空字符串
        }

        // 构建结果字符串
        StringBuilder result = new StringBuilder();
        for (int i = startIndex; i < endIndex; i++) {
            result.append(lines.get(i)).append("\n");
        }

        // 返回结果字符串
        return result.toString();
    }

    /**
     * 分页获取文件内容，使用GB2312编码
     *
     * @param filePath 文件的绝对路径
     * @param pageNumber 页码，从1开始
     * @param pageSize 每页大小
     * @return 指定页的内容
     * @throws IOException 如果文件读取过程中发生错误
     */
    public static String getGbPageContent(String filePath, int pageNumber, int pageSize) throws IOException {
        // 创建一个File对象，表示指定路径的文件
        File file = new File(filePath);

        // 检查文件是否存在且为文件类型
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在或不是一个有效的文件");
        }

        // 初始化结果列表，用于存储文件内容
        List<String> lines = new ArrayList<>();
        // 使用BufferedReader读取文件内容，指定GB2312编码
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GB2312"))) {
            String line;
            while ((line = br.readLine()) != null) {
                lines.add(line);
            }
        }

        // 计算起始索引和结束索引
        int startIndex = (pageNumber - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, lines.size());

        // 检查页码是否有效
        if (startIndex >= lines.size()) {
            return "";
            // 页码超出范围，返回空字符串
        }

        // 构建结果字符串
        StringBuilder result = new StringBuilder();
        for (int i = startIndex; i < endIndex; i++) {
            result.append(lines.get(i)).append("\n");
        }

        // 返回结果字符串
        return result.toString();
    }


    /**
     * 读取并返回一个GB2312编码的文件的内容
     * 此方法主要用于读取指定路径下的文件内容，文件应以GB2312编码
     * 如果文件不存在或路径指向的不是一个文件类型，则抛出IOException异常
     *
     * @param address 文件的路径字符串，用于指定需要读取的文件位置
     * @return 文件的内容，以字符串形式返回
     * @throws IOException 如果文件不存在或不是一个有效的文件类型，或读取过程中发生错误
     */
    public static String getGbFileContent(String address) throws IOException {
        // 创建一个File对象，表示指定路径的文件
        File file = new File(address);

        // 检查文件是否存在且为文件类型
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在或不是一个有效的文件");
        }

        // 初始化结果字符串，用于存储文件内容
        StringBuilder content = new StringBuilder();
        // 使用BufferedReader读取文件内容，指定GB2312编码
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GB2312"))) {
            String line;
            while ((line = br.readLine()) != null) {
                content.append(line).append("\n");
            }
        }

        // 返回结果字符串
        return content.toString();
    }

    /**
     * 判断小说是否存在
     * @param novelPath 
     * @param novelName
     * @return
     */
    public static boolean findEqualsFileByPath(String novelPath, String novelName) {
        String[] novelList = splitNovels(findFileByPath(novelPath));
        for (String novel : novelList){
            if (novel == novelName || novel.equals(novelName)){
                return true;
            }
        }
        return false;
    }

    public static boolean saveNovel(String novelPath, String novelType, String novelName, String author, String novelDescription) {
        //这里的novelPath是已经处理好的小说存储地址
        //先根据小说类型去config中对应的xml文件中添加小说信息，包含小说名字、小说作者、小说简介、小说名称
        OnlineType onlineType = new OnlineType();
        XmlReader.uploadNovel(onlineType.getNOVEL_XML_PATH(novelType),novelType,novelName,author,novelDescription);
        return true;
    }
}
